package org.teremail.message;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.teremail.MailSystemException;
import org.teremail.panto.ContentType;
import org.teremail.panto.ParseException;
import org.teremail.store.Strings;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;

public class MessageHeadersImpl implements MessageHeaders {
    
    private final List<Header> returnPath;
    private final List<Header> received;
    private final ListMultimap<String, Header> headers;
    private final static List<Header> EMPTY_HEADER = ImmutableList.of();

    public MessageHeadersImpl(Header returnPath, Collection<Header> received, 
            ListMultimap<String, Header> headers) {
        
        if (returnPath != null) {
            this.returnPath = ImmutableList.of(returnPath);
        } else {
            this.returnPath = ImmutableList.of();
        }
        this.received = ImmutableList.copyOf(received);
        this.headers = Multimaps.unmodifiableListMultimap(headers);
    }
    
    public MessageHeadersImpl(ListMultimap<String, Header> h) {
        this(null, EMPTY_HEADER, h);
    }

    public String getSubject() {
         return getString(RFC2822.SUBJECT);
    }

    public String getTo() {
        return getString(RFC2822.TO);
    }

    public String getFrom() {
        return getString(RFC2822.FROM);
    }

    public String getReturnPath() {
        return getString(RFC2822.RETURN_PATH);
    }
    
    public String getDate() {
        return getString(RFC2822.DATE);
    }
    
    public String getString(RFC2822 name) {
        return getString(name.getName());
    }
    
    public String getString(String name) {
        Header header = getHeader(name);
        if (header == null) {
            return null;
        } else {
            return header.getValue();
        }
    }
    
    private Header getHeader(String key) {
        Collection<Header> headers = getHeaders(key);
        if (headers.size() == 0) {
            return null;
        } else {
            return headers.iterator().next();
        }
    }
    
    private Collection<Header> getHeaders(String key) {
        if (RFC2822.RETURN_PATH.getName().equalsIgnoreCase(key)) {
            return returnPath;
        } else if (RFC2822.RECEIVED.getName().equalsIgnoreCase(key)) {
            return received;
        } else {
            return headers.get(key.toLowerCase());
        }
    }
    
    public String getBoundary() {
        Header contentTypeHeader = getHeader(RFC2045.CONTENT_TYPE.getName());
        if (contentTypeHeader != null) {
            try {
                ContentType contentType = ContentType.parse(contentTypeHeader.toString());
                return contentType.getBoundary();
            } catch (ParseException e) {
                throw new MailSystemException("Invalid Content-Type header", e);
            }
        } else {
            throw new MailSystemException("No Content-Type header found");
        }
    }

    public Iterator<Header> iterator() {
        return Iterators.concat(returnPath.iterator(), 
                received.iterator(),
                headers.values().iterator());
    }
    
    public String toString() {
        return Strings.join(this, "\r\n");
    }
}
